package cn.com.headfree.file.service.impl;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
//import com.headfree.entity.FileMsg;
//import com.headfree.receive.service.IReceiveService;
import com.gta.edu.sdk.util.StringUtil;

import cn.com.headfree.base.controller.ResultData;
import cn.com.headfree.call.IHumanManageCommonFileServerCall;
import cn.com.headfree.callback.call.FileServerCall;
import cn.com.headfree.entity.TCommonFile;
import cn.com.headfree.file.dao.IFileDao;
import cn.com.headfree.file.service.IFileService;
import cn.com.headfree.util.HttpClientUtils;
import cn.com.headfree.util.MultipartFileToFile;
import cn.com.headfree.vo.file.DealFileVo;
import net.sf.json.JSONObject;

@Service("fileService")
public class FileServiceImpl implements IFileService {
	private static final Logger LOG = LogManager.getLogger(FileServiceImpl.class);
	@Autowired
	private IFileDao fileDao;
	@Autowired
	private IHumanManageCommonFileServerCall humanManageCommonFileServerCall;
	@Autowired
	private FileServerCall fileServerCall;
	/**
	 * 隔离装置服务地址
	 */
	@Value("${isolator.server.location}")
	private String ISOLATOR_SERVER_LOCATION;

	@Override
	public void addFile(List<DealFileVo> files) {
		for (DealFileVo f : files) {
			fileDao.addFile(f);
		}
	}

	@Override
	public void deleteFileByBusinessId(String orignalId) {
		fileDao.deleteFileByBusinessId(orignalId);
	}

	@Override
	public ResultData getFilesByBusinessId(String businessId) {
		return humanManageCommonFileServerCall.getFilesByBusinessId(businessId);
	}

//	@Override
//	public ResultData upload(MultipartFile file, TCommonFile commonFile) {
//		return humanManageCommonFileServerCall.upload(file);
//	}

	@Override
	public ResultData upload(List<MultipartFile> files, TCommonFile commonFile) {
		ResultData rs = new ResultData();
		JSONObject result = new JSONObject();
		// 判断是否存在文件
		if ((null != files) && (0 < files.size())) {
			List<TCommonFile> fileMsgList = new ArrayList<TCommonFile>();
//					//构造List<FileMsg>
//					if(StringUtils.isNotBlank(commonFile.getBusinessId())) {
//						String[] businessIdArr = businessIds.split(",|;|，|；");
//						if((null != businessIdArr)&&(0 < businessIdArr.length)) {
//							for(String businessId:businessIdArr) {
//								fileMsgList.add(new FileMsg(businessId));
//							}
//						}
//					}
			// 文件处理并发送
			MultipartFile multipartFile = null;
			// 多个表单对象-文件名乱码设置
			MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, null,
					Charset.forName("utf-8"));
			List<File> fileList = new ArrayList<File>();
			try {
				entity.addPart("businessId", new StringBody(commonFile.getBusinessId(), Charset.forName("utf-8"))); // 字符参数部分
				if (!StringUtil.isNullOrEmpty(commonFile.getBusinessNode())) {
					entity.addPart("businessNode",
							new StringBody(commonFile.getBusinessNode(), Charset.forName("utf-8"))); // 字符参数部分
				}
				entity.addPart("sysCode", new StringBody(commonFile.getSysCode(), Charset.forName("utf-8"))); // 字符参数部分
				for (int i = 0; i < files.size(); ++i) {
					multipartFile = files.get(i);
					File file = null;
					if (!multipartFile.isEmpty()) {
						try {
							/* 方式1-1 */
							// MultipartFile转File
//									FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file);
//									fileList.add(file);
//							        entity.addPart("file", new FileBody(file,"application/octet-stream", "utf-8")); //表单文件域);
							/* 方式1-2 */
							file = MultipartFileToFile.multipartFileToFile(multipartFile);
							fileList.add(file);
							entity.addPart("file", new FileBody(file, "application/octet-stream", "utf-8")); // 表单文件域);
						} catch (Exception e) {
							e.printStackTrace();
//							result.put("flag", false);
//							result.put("message", "MultipartFile转File异常");
							rs.setSuccess(false);
							rs.setErrorMsg("MultipartFile转File异常");
							LOG.error("保存文件到服务器出错", e.getMessage());
						}

					} else {
//						result.put("flag", false);
//						result.put("message", ((1 == files.size()) ? "上传文件为空" : "第" + i + "个文件为空"));
						rs.setSuccess(false);
						rs.setData(((1 == files.size()) ? "上传文件为空" : "第" + i + "个文件为空"));
						LOG.error(((1 == files.size()) ? "上传文件为空" : "第" + i + "个文件为空"));
					}
				}
				// 执行post操作，并返回response
				HttpResponse response = HttpClientUtils
						.httpPostCall("http://" + ISOLATOR_SERVER_LOCATION + "/comm-file-server/file/upload", entity);
				if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
					String jsonData = EntityUtils.toString(response.getEntity(), "UTF-8");
					LOG.info("保存文件相应结果为--" + jsonData);
					ObjectMapper objectMapper = new ObjectMapper();
					result = objectMapper.readValue(jsonData, new TypeReference<JSONObject>() {
					});
					if (null != result) {
						JSONObject data = JSONObject.fromObject(result.get("data"));
						if (null != data) {
							data = objectMapper.readValue(data.toString(), new TypeReference<JSONObject>() {
							});
//							result.put("data", data);
							TCommonFile t=JSON.parseObject(data.toString(),TCommonFile.class);
							rs.setData(t);
						}
					}
				} else {
//					result.put("flag", false);
//					result.put("message", "保存文件到服务器无响应");
					rs.setSuccess(false);
					rs.setErrorMsg("保存文件到服务器无响应");
					LOG.error("保存文件到服务器无响应");
				}
			} catch (Exception e) {
				e.printStackTrace();
//				result.put("flag", false);
//				result.put("message", "保存文件出错");
				rs.setSuccess(false);
				rs.setErrorMsg("保存文件出错");
				LOG.error("保存文件出错", e.getMessage());
			} finally {
				// 会在本地产生临时文件，用完后需要删除
				if ((null != fileList) && (0 < fileList.size())) {
					for (File file : fileList) {
						if (file.exists()) {
							file.delete();
						}
					}
				}
			}
		} else {
//			result.put("flag", false);
//			result.put("message", "当前无文件上传");
			rs.setSuccess(false);
			rs.setErrorMsg("当前无文件上传");
			LOG.error("当前无文件上传");
		}
//		rs.setData(result);
		return rs;
	}

//	@Override
//	public void download(String fileId) {
//		humanManageCommonFileServerCall.downloadFile(fileId);
//	}

	@Override
	public void getSingleFile(HttpServletResponse response, String fileId) throws Exception {
		if(StringUtils.isNotBlank(fileId)) {
			OutputStream outputStream = null;
			try {
				//发送HttpClient请求
				HttpClient client = new DefaultHttpClient();
				// 定义请求的参数
				URI uri = new URIBuilder("http://"+ISOLATOR_SERVER_LOCATION+"/comm-file-server/file/download").setParameter("fileId", fileId).build();
				HttpGet httpGet = new HttpGet(uri);
				httpGet.addHeader( "User-Agent", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31");
				httpGet.addHeader(HttpHeaders.CONTENT_TYPE, "utf-8");
				HttpResponse httpResponse = client.execute(httpGet);
				if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
					//获取文件名
					String fileName = httpResponse.getHeaders("Content-Disposition")[0].getValue().split("filename=")[1];
					response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename="+fileName);
					
					//得到实体
					HttpEntity entity = httpResponse.getEntity();
					byte[] data = EntityUtils.toByteArray(entity);
			        outputStream = new BufferedOutputStream(response.getOutputStream());
				    outputStream.write(data);
					
					LOG.info("下载文件成功");
				} else {
			        LOG.error("文件下载失败,Http状态码为" + httpResponse.getStatusLine().getStatusCode());
			        throw new Exception("文件下载失败,Http状态码为:" + httpResponse.getStatusLine().getStatusCode());
				}
			} catch (Exception e) {
				e.printStackTrace();
				LOG.error("下载文件出错",e.getMessage());
				throw new Exception(e.getMessage());
			}finally {
				try {
					if(null != outputStream) {
						outputStream.flush();
					    outputStream.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
			        LOG.error("关闭文件流失败",e.getMessage());
			        throw new Exception(e.getMessage());
				}
			}
		}else{
	        LOG.error("参数fileId不可为空");	
	        throw new Exception("参数fileId不可为空");
		}		
	}

	@Override
	public ResultData findFileList(String sysCode, String businessId, String businessNode) {
		return humanManageCommonFileServerCall.findFileList(sysCode,businessId,businessNode);
	}

	@Override
	public ResultData deleteFile(String fileId) {
		return humanManageCommonFileServerCall.deleteFile(fileId);
	}

}
